
package financedata.historicalquotes;

import java.io.BufferedReader;
import java.lang.Exception;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import financedata.historicalquotes.Utils;


public class QuandlGoogleRequest implements IHistoryRequest {
    
    private final String symbol;
    
    private final Calendar from;
    private final Calendar to;
    
    private final Interval interval;
    
    private final static SimpleDateFormat sReqDateFmt;
    static {
        sReqDateFmt = new SimpleDateFormat("yyyy-MM-dd");
    }
    
    //https://www.quandl.com/api/v1/datasets/GOOG/SHA_000001.csv
    //https://www.quandl.com/api/v1/datasets/GOOG/SHE_399001.csv?auth_token=QynRFCR_NLy9MjJ7XPkM
    
    //https://www.quandl.com/api/v1/datasets/OPEC/ORB.csv?trim_start=2001-01-01&trim_end=2002-09-30
    //https://www.quandl.com/api/v1/datasets/OPEC/ORB.csv?sort_order=asc
    //https://www.quandl.com/api/v1/datasets/OPEC/ORB.csv?collapse=monthly
    //https://www.quandl.com/api/v1/datasets/OPEC/ORB.csv?auth_token=FAKETOKEN HERE
     
    private static final String QUANDL_GOOG_BASE_URL 
            = "https://www.quandl.com/api/v1/datasets/GOOG/";
//    private static final String DATA_SOURCE = "GOOG";
    private static final String feiniao2000_token = "QynRFCR_NLy9MjJ7XPkM";
    
    public static final Calendar DEFAULT_FROM = Calendar.getInstance();
    static {
        DEFAULT_FROM.add(Calendar.YEAR, -1);
    }
    public static final Calendar DEFAULT_TO = Calendar.getInstance();
    public static final Interval DEFAULT_INTERVAL = Interval.MONTHLY;
    
    QuandlGoogleRequest(String symbol) {
        this(symbol, DEFAULT_INTERVAL);
    }
    
    QuandlGoogleRequest(String symbol, Interval interval) {
        this.symbol = symbol;
        this.interval = interval;
        
        this.from = DEFAULT_FROM;
        this.to = DEFAULT_TO;
    }
    
    QuandlGoogleRequest(String symbol, Calendar from, Calendar to) {
        this(symbol, from, to, DEFAULT_INTERVAL);
    }
    
    QuandlGoogleRequest(String symbol, Calendar from, Calendar to, Interval interval) {
        this.symbol   = symbol;
        this.from     = from;
        this.to       = to;
        this.interval = interval;
    }
    
    QuandlGoogleRequest(String symbol, Date from, Date to) {
        this(symbol, from, to, DEFAULT_INTERVAL);
    }
    
    QuandlGoogleRequest(String symbol, Date from, Date to, Interval interval) {
        this(symbol, interval);
        this.from.setTime(from);
        this.to.setTime(to);
    }
    
    public List<HistoricalQuote> getResult() {
        
        List<HistoricalQuote> result = new ArrayList<HistoricalQuote>();
        String reqUrl = "noset";
        String currParseLine = null;
        int    parseIdx = 0;
        try {
            Map<String, String> params = new LinkedHashMap<String, String>();
 
            params.put("trim_start", sReqDateFmt.format(from.getTime()));
            params.put("trim_end", sReqDateFmt.format(to.getTime()));

            params.put("auth_token", feiniao2000_token);
            params.put("collapse", this.interval.getTag());

            reqUrl = QUANDL_GOOG_BASE_URL + this.symbol +  ".csv"
                    + "?" + Utils.getURLParameters(params);
            
            // Get CSV
            Utils.logger.log(Level.INFO, ("Sending request: " + reqUrl));
            
            URL request = new URL(reqUrl);
            URLConnection connection = request.openConnection();
            InputStreamReader is = new InputStreamReader(connection.getInputStream());
            BufferedReader br    = new BufferedReader(is);
            String header = br.readLine(); // skip the first line
            if (!header.startsWith("Date,")) {
                return null;
            }
            // Parse CSV
            for(String line = br.readLine(); line != null; line = br.readLine()) {
                parseIdx++;
                currParseLine = Utils.unescape(line);
                HistoricalQuote quote = this.parseCSVLine(line);
                result.add(quote);
            }
            //Utils.logger.log(Level.INFO, ("Parsing CSV line_cnt: " + line_cnt));
        } catch (Exception e) {
            Utils.logger.log(Level.SEVERE, ("Except Url=" + reqUrl + "\n currParseLine:" + currParseLine
                    + " parseIdx=" + parseIdx));
            Utils.logger.log(Level.SEVERE, e.toString(), e);
            return null;
        }
        return result;
    }
    
    private HistoricalQuote parseCSVLine(String line) {
        String[] data = line.split(Utils.QUOTES_CSV_DELIMITER);
        return new HistoricalQuote(this.symbol,
                Utils.parseHistDate(data[0]),
                Utils.getBigDecimal(data[1]),
                Utils.getBigDecimal(data[2]),
                Utils.getBigDecimal(data[3]),
                Utils.getBigDecimal(data[4]),
                Utils.getBigDecimal("0.0"),
                Utils.getBigDecimal(data[5]).longValue()
        );
    }
    
}
